package com.hilinos.common.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Date;

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BaseQo<T, E, L> extends PageVo implements IBaseVo {

    private static final int MODE_EQ = 1;
    private static final int MODE_LIKE = 2;

    @ApiModelProperty("时间查询，开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date startTime;

    @ApiModelProperty("时间查询，结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date endTime;

    /**
     * like查询
     */
    private L l;
    /**
     * 精确查询
     */
    private E e;

    @JsonIgnore
    public QueryWrapper<T> queryWrapper() {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        searchTime(queryWrapper);
        queryWrapper(queryWrapper, e, MODE_EQ);
        queryWrapper(queryWrapper, l, MODE_LIKE);
        return queryWrapper;
    }

    @JsonIgnore
    private void searchTime(QueryWrapper<T> queryWrapper) {
        if (!ObjectUtils.isEmpty(startTime)) {
            queryWrapper.ge("creator_time", startTime);
        }
        if (!ObjectUtils.isEmpty(endTime)) {
            queryWrapper.le("creator_time", endTime);
        }
    }

    @JsonIgnore
    @SneakyThrows
    private void queryWrapper(QueryWrapper<T> queryWrapper, Object entity, int mode) {
        if (ObjectUtils.isEmpty(entity)) {
            return;
        }
        Field[] fields = entity.getClass().getDeclaredFields();
        if (!ObjectUtils.isEmpty(fields)) {
            for (Field field : fields) {
                // static不参与查询
                int modifier = field.getModifiers();
                if ((modifier | Modifier.STATIC) == modifier) {
                    continue;
                }
                // 判断字段上是否存在忽略注解 如果存在则跳过该字段
                QoFieldIgnore qoFieldIgnore = field.getAnnotation(QoFieldIgnore.class);
                if (qoFieldIgnore != null) {
                    continue;
                }
                // 获取字段名
                String tableFieldName = StringUtils.camelToUnderline(field.getName());
                TableField tableField = field.getAnnotation(TableField.class);

                if (!ObjectUtils.isEmpty(tableField) && !ObjectUtils.isEmpty(tableField.value())) {
                    tableFieldName = tableField.value();
                }
                field.setAccessible(true);
                Object value = field.get(this);
                if (!ObjectUtils.isEmpty(value) && !ObjectUtils.isEmpty(tableFieldName)) {
                    switch (mode) {
                        case MODE_EQ:
                            queryWrapper.eq(tableFieldName, value);
                            break;
                        case MODE_LIKE:
                            queryWrapper.like(tableFieldName, value);
                            break;
                    }
                }
            }
        }
    }
}
